package com.centaline.androidsalesblog.activities.news;

import android.content.Intent;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v7.widget.AppCompatEditText;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;

import com.android.volley.VolleyError;
import com.centaline.androidsalesblog.R;
import com.centaline.androidsalesblog.activities.WebActivity;
import com.centaline.androidsalesblog.activities.mine.LoginActivity;
import com.centaline.androidsalesblog.adapter.ChatAdapter;
import com.centaline.androidsalesblog.api.bizcommon.MessageRecordApi;
import com.centaline.androidsalesblog.base.BaseActivity;
import com.centaline.androidsalesblog.constants.AppConstant;
import com.centaline.androidsalesblog.constants.CommonConstant;
import com.centaline.androidsalesblog.constants.ExtraConstant;
import com.centaline.androidsalesblog.events.ConversationUpdate;
import com.centaline.androidsalesblog.events.RongConnectStatus;
import com.centaline.androidsalesblog.events.RongReceiveMessage;
import com.centaline.androidsalesblog.model.businissobject.RongUserInfoBo;
import com.centaline.androidsalesblog.model.databaseobject.StaffDo;
import com.centaline.androidsalesblog.model.databaseobject.UserDo;
import com.centaline.androidsalesblog.model.responseobject.UserFeedBackRo;
import com.centaline.androidsalesblog.rx.database.RxDataBase;
import com.centaline.androidsalesblog.rx.request.RxRequest;
import com.centaline.androidsalesblog.utils.RongUserIdUtil;
import com.centanet.framework.glide.GlideLoad;
import com.centanet.framework.interfaces.IResponseListener;
import com.centanet.framework.utils.WebClickableSpan;
import com.jakewharton.rxbinding.widget.RxTextView;
import com.orhanobut.logger.Logger;
import com.trello.rxlifecycle.ActivityEvent;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.util.ArrayList;
import java.util.List;

import io.rong.imlib.RongIMClient;
import io.rong.imlib.model.Conversation;
import io.rong.imlib.model.Message;
import io.rong.message.TextMessage;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

/**
 * 聊天页面
 */
public class ChatActivity extends BaseActivity implements View.OnClickListener {

    private RecyclerView rv_chat;
    private AppCompatEditText edt_input;
    private Button btn_send;

    private LinearLayoutManager linearLayoutManager;
    private ArrayList<Message> messageArrayList = new ArrayList<>();
    private ChatAdapter chatAdapter;

    private String targetId;
    private RongUserInfoBo currentUserInfo, targetUserInfo;
    private boolean hasHistory;//是否存在历史记录

    private MessageRecordApi messageRecordApi;//消息记录保存

    @Override
    protected int setLayoutId() {
        return R.layout.activity_chat;
    }

    @Override
    protected void findViews() {
        setUniversalToolbar();
        rv_chat = (RecyclerView) findViewById(R.id.rv_chat);
        edt_input = (AppCompatEditText) findViewById(R.id.edt_input);
        btn_send = (Button) findViewById(R.id.btn_send);
    }

    @Override
    protected void initViews() {
        Observable<CharSequence> inputObservable = RxTextView.textChanges(edt_input);
        inputObservable
                .map(new Func1<CharSequence, Boolean>() {
                    @Override
                    public Boolean call(CharSequence charSequence) {
                        return TextUtils.isEmpty(charSequence);
                    }
                })
                .compose(this.<Boolean>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<Boolean>() {
                    @Override
                    public void call(Boolean aBoolean) {
                        btn_send.setEnabled(!aBoolean);
                    }
                });
        linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, true);
        rv_chat.setLayoutManager(linearLayoutManager);

        rv_chat.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (hasHistory) {
                    int size = messageArrayList.size();
                    if (linearLayoutManager.findLastVisibleItemPosition() == size - 1) {
                        rongHistoryMessages(messageArrayList.get(size - 1).getMessageId());
                    }
                }
            }
        });

        chatAdapter = new ChatAdapter(this, GlideLoad.initRound(this), GlideLoad.initUri(this), messageArrayList,
                new ChatAdapter.ChatItemClick() {
                    @Override
                    public void delete(int messageId) {
                        deleteMessageById(messageId);
                    }

                    @Override
                    public void copyText(String text) {

                    }

                    @Override
                    public void imgClick(String position) {

                    }
                }, new WebClickableSpan.SpanOnClick() {
            @Override
            public void click(String text) {
                startActivity(new Intent(ChatActivity.this, WebActivity.class)
                        .putExtra(ExtraConstant.WebUrl, text));
            }
        });
        rv_chat.setAdapter(chatAdapter);

        messageRecordApi = new MessageRecordApi(getClass(), UserFeedBackRo.class,
                new IResponseListener<UserFeedBackRo>() {
                    @Override
                    public void onResponse(UserFeedBackRo userFeedBackRo) {

                    }

                    @Override
                    public void onErrorResponse(VolleyError error) {

                    }
                });


        EventBus.getDefault().register(this);

        targetId = getIntent().getStringExtra(ExtraConstant.TargetId);

        messageRecordApi.setRcReceiver(targetId);
        switch (getIntent().getIntExtra(ExtraConstant.MessageTarget, 0)) {
            case 1:
                messageRecordApi.setTarget("ershoufang");
                break;
            case 2:
                messageRecordApi.setTarget("zufang");
                break;
            case 3:
                messageRecordApi.setTarget("loupan");
                break;
            default:
                break;
        }

        messageRecordApi.setTargetValue(getIntent().getStringExtra(ExtraConstant.MessageTargetValue));
        checkLogin();
    }

    @Override
    protected void onDestroy() {
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }

    /**
     * 检查登录状态
     */
    private void checkLogin() {
        if (AppConstant.IsLogin) {
            initChatList();
        } else {
            startActivityForResult(new Intent(this, LoginActivity.class), CommonConstant.REQ_LOGIN);
        }
    }

    /**
     * 连接状态
     */
    @Subscribe
    public void onEventMainThread(RongConnectStatus rongConnectStatus) {
        cancelLoadingDialog();
        switch (rongConnectStatus.getStatus()) {
            case 0://连接成功
                initChatList();
                break;
            default:
                toast("连接失败!");
                finish();
                break;
        }
    }

    /**
     * 新消息
     */
    @Subscribe
    public void onEventMainThread(RongReceiveMessage receiveMessage) {
        if (receiveMessage != null) {
            Message message = receiveMessage.getMessage();
            if (message != null &&
                    message.getTargetId().equals(targetId)) {
                updateSendMessage(message.getMessageId());
            }
        }
    }

    /**
     * 初始化聊天列表
     */
    private void initChatList() {
        currentUserInfo();
        targetUserInfo();
        rongLatestMessages();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_send:
                sendTextMessage();
                break;
            default:
                break;
        }
    }

    /**
     * 发送文本消息
     */
    private void sendTextMessage() {
        String content = edt_input.getText().toString();
        sendTextMessage(content);
    }

    /**
     * 发送文本消息
     */
    private void sendTextMessage(final String content) {
        messageRecord(content);
        if (RongIMClient.getInstance() != null) {
            RongIMClient.getInstance().sendMessage(Conversation.ConversationType.PRIVATE,
                    targetId,
                    TextMessage.obtain(content),
                    null,
                    null,
                    new RongIMClient.SendMessageCallback() {
                        @Override
                        public void onSuccess(Integer integer) {
                            Logger.d("SendMessageCallback onSuccess : %d", integer);
                            updateSendMessage(integer);
                        }

                        @Override
                        public void onError(Integer integer, RongIMClient.ErrorCode errorCode) {
                            Logger.d("SendMessageCallback onError : %s", errorCode.getMessage());
                        }
                    },
                    new RongIMClient.ResultCallback<Message>() {
                        @Override
                        public void onSuccess(Message message) {
                            Logger.d("ResultCallback onSuccess status : %s", message.getSentStatus().name());
                            messageArrayList.add(0, message);
                            chatAdapter.notifyItemInserted(0);
                            rv_chat.smoothScrollToPosition(0);
                            updateConversation(0);
                        }

                        @Override
                        public void onError(RongIMClient.ErrorCode errorCode) {
                            Logger.d("ResultCallback onError : %s", errorCode.getMessage());
                        }
                    });
            edt_input.setText(null);
        }
    }

    /**
     * 更新发送的消息[成功or失败]
     */
    private void updateSendMessage(int messageId) {
        if (RongIMClient.getInstance() != null) {
            RongIMClient.getInstance().getMessage(messageId, new RongIMClient.ResultCallback<Message>() {
                @Override
                public void onSuccess(Message message) {
                    if (message != null) {
                        int size = messageArrayList.size();
                        boolean isInList = false;//是否在列表中
                        for (int i = 0; i < size; i++) {
                            if (message.getMessageId() == messageArrayList.get(i).getMessageId()) {
                                isInList = true;
                                messageArrayList.remove(i);
                                messageArrayList.add(i, message);
                                chatAdapter.notifyItemChanged(i);
                                break;
                            }
                        }
                        if (!isInList) {
                            messageArrayList.add(0, message);
                            chatAdapter.notifyItemInserted(0);
                            rv_chat.smoothScrollToPosition(0);
                            clearUnread();
                        }
                    }
                }

                @Override
                public void onError(RongIMClient.ErrorCode errorCode) {
                    Logger.d("getMessage onError : %s", errorCode.getMessage());
                }
            });
        }
    }

    /**
     * 获取最新的消息
     */
    private void rongLatestMessages() {
        if (RongIMClient.getInstance() != null) {
            RongIMClient.getInstance().getLatestMessages(Conversation.ConversationType.PRIVATE, targetId, 10, new RongIMClient.ResultCallback<List<Message>>() {
                @Override
                public void onSuccess(List<Message> messages) {
                    if (messages != null) {
                        messageArrayList.addAll(messages);
                        chatAdapter.notifyItemRangeChanged(0, 10);
                        hasHistory = messages.size() == 10;
                        NotificationManagerCompat.from(ChatActivity.this).cancelAll();
                        clearUnread();
                    }
                }

                @Override
                public void onError(RongIMClient.ErrorCode errorCode) {
                    snack(errorCode.getMessage());
                }
            });
        }
    }

    /**
     * 获取历史消息记录
     */
    private void rongHistoryMessages(final int messageId) {
        if (RongIMClient.getInstance() != null) {
            RongIMClient.getInstance().getHistoryMessages(Conversation.ConversationType.PRIVATE, targetId, messageId, 10,
                    new RongIMClient.ResultCallback<List<Message>>() {
                        @Override
                        public void onSuccess(List<Message> messages) {
                            if (messages != null) {
                                messageArrayList.addAll(messages);
                                int size = messageArrayList.size();
                                chatAdapter.notifyItemRangeChanged(size - 10, size);
                                hasHistory = messages.size() == 10;
                            } else {
                                hasHistory = false;
                            }
                        }

                        @Override
                        public void onError(RongIMClient.ErrorCode errorCode) {
                            snack(errorCode.getMessage());
                        }
                    });
        } else {
            hasHistory = false;
        }
    }

    /**
     * 清除当前用户未读消息状态
     */
    private void clearUnread() {
        if (RongIMClient.getInstance() != null) {
            RongIMClient.getInstance().clearMessagesUnreadStatus(Conversation.ConversationType.PRIVATE,
                    targetId,
                    new RongIMClient.ResultCallback<Boolean>() {
                        @Override
                        public void onSuccess(Boolean aBoolean) {
                            if (aBoolean) {
                                updateConversation(1);
                            }
                        }

                        @Override
                        public void onError(RongIMClient.ErrorCode errorCode) {

                        }
                    });
        }
    }

    /**
     * 根据messageId删除消息
     */
    private void deleteMessageById(final int messageId) {
        if (RongIMClient.getInstance() != null) {
            RongIMClient.getInstance().deleteMessages(new int[]{messageId}, new RongIMClient.ResultCallback<Boolean>() {
                @Override
                public void onSuccess(Boolean aBoolean) {
                    if (aBoolean) {
                        int size = messageArrayList.size();
                        for (int i = 0; i < size; i++) {
                            if (messageId == messageArrayList.get(i).getMessageId()) {
                                messageArrayList.remove(i);
                                chatAdapter.notifyItemRemoved(i);
                                chatAdapter.notifyItemChanged(i == 0 ? 0 : i - 1);
                                break;
                            }
                        }
                        updateConversation(1);
                    } else {
                        snack("删除失败");
                    }
                }

                @Override
                public void onError(RongIMClient.ErrorCode errorCode) {
                    snack("删除失败");
                }
            });
        } else {
            int size = messageArrayList.size();
            for (int i = 0; i < size; i++) {
                if (messageId == messageArrayList.get(i).getMessageId()) {
                    messageArrayList.remove(i);
                    chatAdapter.notifyItemRemoved(i);
                    break;
                }
            }
            updateConversation(1);
        }
    }

    /**
     * 更新会话
     *
     * @param status 按需更新
     */
    private void updateConversation(int status) {
        EventBus.getDefault().post(new ConversationUpdate(status, targetId));
    }

    /**
     * 消息记录存
     */
    private void messageRecord(String content) {
        messageRecordApi.setMsgType("RC:TxtMsg");
        messageRecordApi.setMsgContent(content);
        messageRecordApi.startRequest();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (RESULT_OK == resultCode) {
            switch (requestCode) {
                case CommonConstant.REQ_LOGIN:
                    showLoadingDialog();
                    break;
                default:
                    break;
            }
        } else {
            finish();
        }
    }

    /**
     * 当前登录用户信息
     */
    private void currentUserInfo() {
        RxDataBase.getUser()
                .map(new Func1<UserDo, RongUserInfoBo>() {
                    @Override
                    public RongUserInfoBo call(UserDo userDo) {
                        if (userDo == null) {
                            return null;
                        } else {
                            return new RongUserInfoBo(RongUserIdUtil.getCustomerId(userDo.getUserId()),
                                    userDo.getNickName(), userDo.getUserPhotoUrl(), userDo.getPhone());
                        }
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(this.<RongUserInfoBo>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<RongUserInfoBo>() {
                    @Override
                    public void call(RongUserInfoBo rongUserInfoBo) {
                        if (rongUserInfoBo != null) {
                            messageRecordApi.setRcSender(rongUserInfoBo.getUserId());
                            currentUserInfo = rongUserInfoBo;
                            chatAdapter.setCurrentUserInfo(currentUserInfo);
                            if (!TextUtils.isEmpty(getIntent().getStringExtra(ExtraConstant.MessageCome))) {
                                sendTextMessage(getIntent().getStringExtra(ExtraConstant.MessageCome));
                            }
                        }
                    }
                });
    }

    /**
     * 聊天用户信息
     */
    private void targetUserInfo() {
        Observable.concat(RxDataBase.rongUserInfo(targetId)
                        .subscribeOn(Schedulers.io()),
                RxRequest.rongUserInfo(ChatActivity.class, targetId)
                        .map(new Func1<StaffDo, RongUserInfoBo>() {
                            @Override
                            public RongUserInfoBo call(StaffDo staffDo) {
                                saveTargetStaff(staffDo);
                                if (staffDo == null) {
                                    return null;
                                } else {
                                    return new RongUserInfoBo(RongUserIdUtil.getSatffId(staffDo.getStaffNo()),
                                            staffDo.getCnName(),
                                            staffDo.getImgUrl(),
                                            staffDo.getMobile());
                                }
                            }
                        }))
                .first()
                .compose(this.<RongUserInfoBo>bindUntilEvent(ActivityEvent.DESTROY))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<RongUserInfoBo>() {
                    @Override
                    public void call(RongUserInfoBo rongUserInfoBo) {
                        if (rongUserInfoBo != null) {
                            targetUserInfo = rongUserInfoBo;
                            setToolbarTitle(rongUserInfoBo.getNickName());
                            if (getSupportActionBar() != null) {
                                getSupportActionBar().setSubtitle(R.string.online);
                            }
                            chatAdapter.setTargetUserInfo(targetUserInfo);
                        }
                    }
                });
    }

    /**
     * 保存聊天用户信息
     */
    private void saveTargetStaff(StaffDo staffDo) {
        RxDataBase.saveStaff(staffDo)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(this.<Void>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {

                    }
                });
    }
}
